package org.mashart.pink.m.ws;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import org.mashart.pink.m.gps.Waypoint;

/**
 * The only implementation of HTTP client we have at the moment
 * @see WsConnector
 *
 * TODO make it run in a separate thread
 */
public class RestfulClient implements WsConnector {

    /**
     * <code>true</code> if this instance has been configured already
     * @see <code>configure()</code>
     */
    private boolean configured;

    /**
     * URL where to post GPS data to
     */
    private String url;
    /* TODO make it configurable from a UI */

    /**
     * HTTP connection to the server
     */
    private HttpConnection conn;

    /**
     * HTTP request data
     */
    OutputStream ostream;

    /**
     * HTTP response stream
     */
    InputStream istream;

    /**
     * Constructor. Doesn't do much of useful things */
    public RestfulClient() {
        this.configured = false;
        this.ostream = null;
        this.istream = null;
    }

    /**
     * Preparation for <code>initialize()</code>
     *
     * TODO I'd like to be able to configure this from a UI
     */
    public int configure() {
//        url = "http://pink.mashart.org/users/bertha/update_current_pos";
        //url = "http://193.205.213.199:3000/users/carlee/update_current_pos";
        url = "http://localhost:8000/pinkrws/update_current_pos";
        configured = true;
        return 1;
    }

    /**
     * Doesn't do anything at the moment
     */
    public int initialize() {
        if (!configured) {
            return -1;
        }

        /* TODO is it possible we open HTTP connection the server here
         *      and keep it always that way? Would it be a better way?
         */

        
        /*
        try {
            // Open HTTP connection to the specified URL
            conn = (HttpConnection) Connector.open(url);

            // Set the request method and headers
            conn.setRequestMethod(HttpConnection.POST);

            // Open the stream
            ostream = conn.openOutputStream();

        } catch (IOException ex) {
            // something went wrong
            return -1;
        }*/

        // test if the internet is available
//        return push("Test".getBytes());
        return -1;
    }

    /**
     * POST data in bytes to the server
     *
     * Opens HTTP connection, <code>OutputStream</code>, pushes the data
     * and closes all open streams
     */
    public int push(byte[] b) {
        int res = 1;
        try {
            if(ostream == null){
            // Open HTTP connection to the specified URL
                conn = (HttpConnection) Connector.open(url, Connector.READ_WRITE);
                // Set the request method and headers
                conn.setRequestMethod(HttpConnection.POST);
                // Open the stream
                ostream = conn.openDataOutputStream();
            }
            ostream.write(b);
            System.out.println(new String(b));

            res = conn.getResponseCode();
//            ostream.flush();

            //skipResponse();

            /* TODO error response code handling */
            long len = conn.getLength();
            if (len > 0)
                istream = conn.openInputStream();
            istream.skip(len);
            terminate();
        } catch (IOException ex) {
            // can't send to our web service
            res = -1;
            /* TODO try to reconnect instead */
        }

        return res;
    }

    /**
     * Closes all open stream and HTTP connection
     */
    public int terminate() {
        int res = 1;
        // Closing input stream
        try {
            if (istream != null) { istream.close(); }
        } catch (IOException ex) {
            // something went wrong
            res = -1;
        } finally {
            istream = null;
        }

        // Closing output stream
        try {
            if (ostream != null) { ostream.close(); }
        } catch (IOException ex) {
            // something went wrong
            res = -1;
        } finally {
            ostream = null;
        }

        // Closing HTTP connection
        try {
            if (conn != null) { conn.close(); }
        } catch (IOException ex) {
            // something went wrong
            res = -1;
        } finally {
            conn = null;
        }
        
        return res;
    }
}
